#include <iostream>
#include <string>
using namespace std;

// 虚析构和纯虚析构

class Animal
{
public:
    virtual void shout() = 0;

    Animal()
    {
        cout << "Animal 构造函数调用" << endl;
    }

    //利用虚析构可以解决 父类指针释放子类对象时不干净的问题
    // virtual ~Animal()
    // {
    //     cout << "Animal 析构函数调用" << endl;
    // }

    //纯虚析构  需要声明，也需要实现
    //有纯虚析构，该类属于抽象类，无法实例化
    virtual ~Animal() = 0;
};

//纯虚析构 需要具体实现
Animal::~Animal()
{
    cout << "Animal 纯虚析构函数调用" << endl;
}


class Cat:public Animal
{
public:
    string* name;
    
    virtual void shout()
    {
        cout << *name << "小猫在叫：喵喵喵……" << endl;
    }

    Cat(string name)
    {
        cout << "Cat 构造函数调用" << endl;
        this->name = new string(name);
    }

    ~Cat()
    {
        cout << "Cat 析构函数调用" << endl;
        if (name != NULL) {
            delete name;
        }
    }
};

void test1()
{
    Animal* animal = new Cat("汤姆");
    animal->shout();
    //父类指针在析构的时候，不会调用子类的析构函数 -- 若父类的析构函数是virtual修饰，则会自动调用 子类的虚构函数
    //导致子类如果有堆区属性，会出现内存浪费
    delete animal;
}


class A
{
public:
    A(){cout<<"A::A()"<<endl;}
    
    virtual ~A() 
    { cout<<"A::~A()"<<endl; }
};

class B: public A {
public:
    B(int i) { 
        buf=new char[i]; 
        cout<<"B::B(int)" <<endl; 
    }
    
    virtual ~B() {
        delete [] buf;
        cout<<"B::~B() called. "<<endl; }
    
private:
    char *buf;
};

void test2(){
    A *a=new B(15);
    delete a;//自动调用子类B的析构函数

}

int main()
{
    test1();
    cout << "================" << endl;
    test2();
        
    return 0;
}